package com.finance.framework.shiro;

import com.finance.base.enums.StateEnum;
import com.finance.system.bean.pojo.Role;
import com.finance.system.bean.pojo.User;
import com.finance.system.service.IRoleService;
import com.finance.system.service.IUserService;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.*;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;
import org.apache.shiro.subject.Subject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import javax.annotation.Resource;
import java.util.List;


@Component
public class UserRealm extends AuthorizingRealm {
	protected final Logger logger = LoggerFactory.getLogger(this.getClass());

	@Resource
	private IUserService userService;

	@Autowired(required = false)
	private IRoleService roleService;

	/**
	 * 获取用户所拥有的所有角色
	 */
	@Override
	protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
		Subject currentUser = SecurityUtils.getSubject();
		User user = (User)currentUser.getSession().getAttribute("authUser");
		List<Role> roleList = this.roleService.list4User(user);
		SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();
		for(Role role : roleList){
			if(role.getState()==StateEnum.Valid.getState()) {
                info.addRole(role.getId().toString());
            }
		}
		return info;
	}

	@Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
			String code = (String) token.getPrincipal();
			String passwd = new String((char[]) token.getCredentials());
			Subject currentUser = SecurityUtils.getSubject();
			User user = this.userService.getByCode(code);
			if (this.userService.verifyPass(user, passwd)) {
				currentUser.getSession().setAttribute("authUser", user);
				return new SimpleAuthenticationInfo(code, passwd, "UserRealm");
			} else if (user.getState() == StateEnum.Invalid.getState()) {
				throw new AccountException("账号已停用");
			} else {
				throw new AccountException("账号不存在或密码不匹配");
			}
	}

	@Override
	public void clearCachedAuthorizationInfo(PrincipalCollection principals) {
		super.clearCachedAuthorizationInfo(principals);
	}

	@Override
	public void clearCachedAuthenticationInfo(PrincipalCollection principals) {
		super.clearCachedAuthenticationInfo(principals);
	}

	@Override
	public void clearCache(PrincipalCollection principals) {
		super.clearCache(principals);
	}

	public void clearAllCachedAuthorizationInfo() {
		getAuthorizationCache().clear();
	}

	public void clearAllCachedAuthenticationInfo() {
		getAuthenticationCache().clear();
	}

	public void clearAllCache() {
		clearAllCachedAuthenticationInfo();
		clearAllCachedAuthorizationInfo();
	}
}